package com.seh.contentcenter.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.seh.contentcenter.dto.GoodsDTO;
import com.seh.contentcenter.dto.OrderAndGoodsDTO;
import com.seh.contentcenter.dto.OrderDTO;
import com.seh.contentcenter.dto.UserDTO;
import com.seh.contentcenter.entity.Goods;
import com.seh.contentcenter.entity.Order;
import com.seh.contentcenter.feignclient.UserCenterFeignClient;
import com.seh.contentcenter.mapper.GoodsMapper;
import com.seh.contentcenter.mapper.OrderMapper;
import com.seh.contentcenter.service.OrderService;
import com.seh.contentcenter.service.es.ESGoodsService;
import com.seh.contentcenter.utils.DTOUtil;
import com.seh.contentcenter.utils.UserUtil;
import com.seh.contentcenter.utils.WrapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsServiceImpl goodsService;

    @Autowired
    private RedisTemplate<String, Object> objectRedisTemplate;

    @Autowired
    private UserCenterFeignClient userCenterFeignClient;

    @Autowired
    private ESGoodsService esGoodsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static int pageSize = 4;

    /**
     * 新增订单信息
     * @param order
     * @return
     */
    @Override
    public String addOrder(Order order) {
        String lockKey = "addOrderLock";
        String lockValue = UUID.randomUUID().toString();
        Integer goodsStatus = goodsMapper.selectById(order.getGoodsId()).getGoodsStatus();
        try {
            // 尝试获取锁
            Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10));
            if (lockAcquired != null && lockAcquired && goodsStatus == 0) {
                // 成功获取锁，执行业务逻辑
                int insert = orderMapper.insert(order);
                if (insert > 0) {
                    Goods goods = new Goods();
                    goods.setGoodsId(order.getGoodsId());
                    goods.setGoodsPrice(order.getOrderPrice());
                    goods.setGoodsStatus(1);
                    goodsMapper.updateById(goods);
                    objectRedisTemplate.delete("goods");
                    objectRedisTemplate.delete("goodsAddress");
                    esGoodsService.updateGoodsStatus(order.getGoodsId(), 1);
                    return "添加成功" + order.getOrderId();
                } else {
                    return "添加失败";
                }
            } else {
                // 获取锁失败，另一个进程已在添加订单
                return "添加失败，请稍后再试";
            }
        } finally {
            // 释放锁
            String currentLockValue = String.valueOf(redisTemplate.opsForValue().get(lockKey));
            if (currentLockValue != null && currentLockValue.equals(lockValue)) {
                redisTemplate.delete(lockKey);
            }
        }
    }



    /**
     * 根据用户id，查询此用户所用的订单信息
     * @param userId
     * @return
     */
    @Override
    public List<OrderDTO> findAllOrderByUserId(Integer userId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        List<OrderDTO> orderDTOList = new ArrayList<>();
        orderList.forEach(f -> {
            OrderDTO orderDTO = DTOUtil.convertOrder(f);
            orderDTOList.add(orderDTO);
        });
        return orderDTOList;
    }

    /**
     * 通过主键id，查询订单的详细信息
     * @param orderId
     * @return
     */
    @Override
    public OrderDTO selectOrderById(Integer orderId) {
        //这段代码采用连表查询，只对数据库进行一次查询
        MPJLambdaWrapper<Order> orderMPJLambdaWrapper = new MPJLambdaWrapper<>();
        orderMPJLambdaWrapper.selectAll(Order.class);
        orderMPJLambdaWrapper.selectAll(Goods.class);
        orderMPJLambdaWrapper.eq(Order::getOrderId, orderId);
        orderMPJLambdaWrapper.leftJoin(Goods.class, Goods::getGoodsId, Order::getGoodsId);
        List<OrderAndGoodsDTO> orderAndGoodsDTO = orderMapper.selectJoinList(OrderAndGoodsDTO.class, orderMPJLambdaWrapper);
        OrderDTO orderDTO = new OrderDTO();
        try {
            BeanUtil.copyProperties(orderAndGoodsDTO.get(0), orderDTO);
        } catch (Exception e) {
            return null;
        }

        GoodsDTO goodsDTO = new GoodsDTO();
        goodsDTO.setGoodsId(orderAndGoodsDTO.get(0).getGoodsId());
        goodsDTO.setUserId(orderAndGoodsDTO.get(0).getUserId());
        goodsDTO.setGoodsName(orderAndGoodsDTO.get(0).getGoodsName());
        goodsDTO.setGoodsDesc(orderAndGoodsDTO.get(0).getGoodsDesc());
        orderDTO.setGoodsDTO(goodsDTO);

        return orderDTO;
    }

    /**
     * 根据订单id，删除订单
     * @param orderId
     * @return
     */
    @Override
    public String deleteOrderById(Integer orderId) {
        int i = orderMapper.deleteById(orderId);
        if (i == 1) {
            return "删除成功";
        }
        return "删除失败";
    }

    /**
     * 通过下单用户id和订单状态，获取卖出的商品
     * @param sellerId
     * @return
     */
    @Override
    public List<OrderDTO> findAllOrderByUserIdAndOrderStatus(Integer sellerId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seller_id", sellerId)
                .notLike("order_status", 0)
                .orderByAsc("order_status");
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        
        List<OrderDTO> orderDTOList = new ArrayList<>();
        orderList.forEach(f -> {
            OrderDTO orderDTO = DTOUtil.convertOrder(f);
            GoodsDTO goodsDTO = goodsService.findById(f.getGoodsId());
            orderDTO.setGoodsDTO(goodsDTO);
            UserDTO userDTO = UserUtil.getUserDTOFromCache(f.getUserId(), objectRedisTemplate, userCenterFeignClient);
            orderDTO.setUserDTO(userDTO);
            UserDTO sellerDTO = UserUtil.getUserDTOFromCache(goodsDTO.getUserId(), objectRedisTemplate, userCenterFeignClient);
            goodsDTO.setUserDTO(sellerDTO);
            orderDTOList.add(orderDTO);
        });
        return orderDTOList;
    }

    /**
     * 查询我卖出的
     * @param sellerId
     * @return
     */
    @Override
    public List<OrderDTO> findAllOrderByUserHasSold(Integer sellerId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seller_id", sellerId);
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        List<OrderDTO> orderDTOList = new ArrayList<>();
        orderList.forEach(f -> {
            OrderDTO orderDTO = DTOUtil.convertOrder(f);
            GoodsDTO goodsDTO = goodsService.findById(f.getGoodsId());
            orderDTO.setGoodsDTO(goodsDTO);
            orderDTOList.add(orderDTO);
        });
        return orderDTOList;
    }

    /**
     * 用户支付商品之后，更新订单的状态
     * @param order
     * @return
     */
    @Override
    public String updateOrderStatus(Order order) {
        int update = orderMapper.updateById(order);
        if (update == 1) {
            return "更新成功";
        }
        return "更新失败";
    }

    /**
     * 获取所有<我买到的>
     * @param userId
     * @param pageIndex
     * @return
     */
    @Override
    public List<OrderDTO> findAllOrderByBought(Integer userId, Integer pageIndex) {
        Page<Order> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<Order> queryWrapper =
                WrapperUtil.pageOrderStatusWrapper(userId, "create_time", "user_id", "order_status");
        page = orderMapper.selectPage(page, queryWrapper);
        List<Order> orderList = page.getRecords();
        List<OrderDTO> orderDTOList = new ArrayList<>();
        /*orderList.forEach(f -> {
            OrderDTO orderDTO = DTOUtil.convertOrder(f);
            GoodsDTO goodsDTO = goodsService.findById(f.getGoodsId());
            orderDTO.setGoodsDTO(goodsDTO);
            UserDTO customerDTO = UserUtil.getUserDTOFromCache(orderDTO.getUserId(), objectRedisTemplate, userCenterFeignClient);
            orderDTO.setUserDTO(customerDTO);
            UserDTO userDTO = UserUtil.getUserDTOFromCache(goodsDTO.getUserId(), objectRedisTemplate, userCenterFeignClient);
            goodsDTO.setUserDTO(userDTO);
            orderDTOList.add(orderDTO);
        });*/
        orderList.forEach(f -> {
            OrderDTO orderDTO = DTOUtil.convertOrder(f);
            GoodsDTO goodsDTO = goodsService.findById(f.getGoodsId());
            orderDTO.setGoodsDTO(goodsDTO);
            UserDTO customerDTO = UserUtil.getUserDTOFromCache(orderDTO.getUserId(), objectRedisTemplate, userCenterFeignClient);
            orderDTO.setUserDTO(customerDTO);

            if (goodsDTO != null) {
                Integer goodsDTOUserId = goodsDTO.getUserId();
                if (goodsDTOUserId != null) {
                    UserDTO userDTO = UserUtil.getUserDTOFromCache(goodsDTOUserId, objectRedisTemplate, userCenterFeignClient);
                    goodsDTO.setUserDTO(userDTO);
                }
            }

            orderDTOList.add(orderDTO);
        });
        return orderDTOList;
    }

    /**
     * 收货成功，修改订单信息
     * @param orderId
     * @return
     */
    @Override
    public String updateOrderDone(Integer orderId) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setOrderStatus(2);
        int update = orderMapper.updateById(order);
        if (update == 1) {
            return "更新成功";
        }
        return "更新失败";
    }

    /**
     * 若支付失败，则删除订单
     * @param orderId
     * @return
     */
    @Override
    public String updateOrderStatus(Integer orderId) {
        System.out.println("orderId:" + orderId);
        Order order1 = orderMapper.selectById(orderId);
        Goods goods = new Goods();
        goods.setGoodsId(order1.getGoodsId());
        goods.setGoodsStatus(0);
        goods.setGoodsPrice(order1.getOrderPrice());
        goodsMapper.updateById(goods);
        esGoodsService.updateGoodsStatus(order1.getGoodsId(), 0);
        int update = orderMapper.deleteById(orderId);
        if (update > 0) {
            return "修改成功";
        }
        return "修改失败";
    }

}
